package com.example.demospringmybatisplus.config;

import java.util.List;
import java.util.Optional;
import java.util.concurrent.Executor;
import java.util.concurrent.ForkJoinPool;
import java.util.function.Supplier;
import java.util.stream.Collectors;

import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.ObjectProvider;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.lang.Nullable;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.util.CollectionUtils;
import org.springframework.util.function.SingletonSupplier;

import com.example.demospringmybatisplus.annotation.SecureInvokeConfigurer;
import com.example.demospringmybatisplus.aspect.SecureInvokeAspect;
import com.example.demospringmybatisplus.dao.SecureInvokeRecordDao;
import com.example.demospringmybatisplus.mapper.SecureInvokeRecordMapper;
import com.example.demospringmybatisplus.service.MQProducerService;
import com.example.demospringmybatisplus.service.SecureInvokeService;

/**
 * TransactionAutoConfiguration事务配置器
 *
 * @author hauhua
 * @DATE 2025/1/21
 */
@Configuration
@EnableScheduling
@MapperScan(basePackageClasses = SecureInvokeRecordMapper.class)
@Import({SecureInvokeAspect.class, SecureInvokeRecordDao.class})
public class TransactionAutoConfiguration {
    @Nullable
    protected Executor executor;

    /**
     * 通过自动注入的 SecureInvokeConfigurer 配置来设置 executor
     */
    @Autowired
    void setConfigurers(ObjectProvider<SecureInvokeConfigurer> configurers) {
        Supplier<SecureInvokeConfigurer> configurer = SingletonSupplier.of(() -> {
            List<SecureInvokeConfigurer> candidates = configurers.stream().collect(Collectors.toList());
            if (CollectionUtils.isEmpty(candidates)) {
                return null;
            }
            if (candidates.size() > 1) {
                throw new IllegalStateException("Only one SecureInvokeConfigurer may exist");
            }
            return candidates.get(0);
        });
        // 使用单个配置实例获取 Executor，如果为空则使用默认的 ForkJoinPool.commonPool()
        executor = Optional.ofNullable(configurer.get())
            .map(SecureInvokeConfigurer::getSecureInvokeExecutor)
            .orElse(ForkJoinPool.commonPool());
    }

    @Bean
    public SecureInvokeService getSecureInvokeService(SecureInvokeRecordDao dao) {
        return new SecureInvokeService(dao, executor);
    }

    @Bean
    public MQProducerService getMQProducer() {
        return new MQProducerService();
    }
}
